package com.xxl.job.executor.sjbank.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.JsonNode;
import com.mashape.unirest.http.Unirest;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.executor.sjbank.mapper.*;
import com.xxl.job.executor.sjbank.pojo.*;
import com.xxl.job.executor.sjbank.pojo.model.AutoDistribute;
import com.xxl.job.executor.sjbank.pojo.model.CaseJoinAcct;
import com.xxl.job.executor.sjbank.pojo.model.QueryLink;
import com.xxl.job.executor.sjbank.service.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @author tsu
 * @description 针对表【cfg_activity(自动分案管理表)】的数据库操作Service实现
 * @createDate 2024-03-25 10:03:06
 */
@Service
public class CfgActivityServiceImpl extends ServiceImpl<CfgActivityMapper, CfgActivity>
        implements CfgActivityService {

    @Value("${ccrm.token}")
    private String cCrmToken;

    @Value("${ccrm.url}")
    private String cCrmurl;
    @Resource
    FiCreditcasesService fiCreditcasesService;
    @Resource
    FiCreditcasesMapper fiCreditcasesMapper;
    @Resource
    CfgActivityOthergrplinkService cfgActivityOthergrplinkService;
    @Resource
    FiCreditcasesHistService fiCreditcasesHistService;
    @Resource
    FiDistbatchHistService fiDistbatchHistService;
    @Resource
    CfgActivityQuerylinkMapper cfgActivityQuerylinkMapper;
    @Resource
    CfgActivityExecdayMapper cfgActivityExecdayMapper;

    @Override
    public void autoDistribute() {
        List<CfgActivity> list = list(new QueryWrapper<CfgActivity>()
                .eq("status", 1)  //<=  >=
                .and(i -> i.le("availableday1", LocalDate.now()).or().isNull("availableday1"))
                .and(i -> i.ge("availableday2", LocalDate.now()).or().isNull("availableday2"))
                .and(i -> i.isNull("distdaymode").or().eq("distdaymode", "0").or().exists("select 1 from cfg_activity_execday cae where cfg_activity.activityid=cae.activityid and cae.execdate=TRUNC(SYSDATE)"))
                .orderByAsc("rank")
        );
        XxlJobHelper.log("XXXL-JOB-autoDistribute 分配模版:" + list.size() + "个");
        // 分配案件
        disUsersToCases(list);
    }

    private void searchCases(List<CfgActivity> list) {
        list.forEach(item -> {
            try {
                Random random = new Random();
                int id = random.nextInt(100);
                // 获取当前日期和时间
                LocalDateTime currentDateTime = LocalDateTime.now();
                String formatter = currentDateTime.format(DateTimeFormatter.ofPattern("yyMMddHHmm"));
                String batchid = "A" + formatter + String.format("%03d", id);
                Date distdt = new Date();

                Date binddt = null;
                long diffInDays = 0;
                // 案件自动回收时间
                if (Objects.equals(item.getDistdaymode(), "1")) {
                    CfgActivityExecday cfgActivityExecday = cfgActivityExecdayMapper.selectOne(new QueryWrapper<CfgActivityExecday>().eq("activityid", item.getActivityid()).eq("execdate", LocalDate.now()));
                    binddt = cfgActivityExecday.getRecydate();
                    long diffInMillies = Math.abs(cfgActivityExecday.getRecydate().getTime() - cfgActivityExecday.getExecdate().getTime());
                    diffInDays = TimeUnit.DAYS.convert(diffInMillies, TimeUnit.MILLISECONDS);
                } else {
                    Calendar calendar = Calendar.getInstance();
                    calendar.setTime(new Date());
                    calendar.add(Calendar.DATE, item.getBindday());
                    binddt = calendar.getTime();
                }

                // 查询自定义条件
                List<QueryLink> querylink = cfgActivityQuerylinkMapper.selectJoinList(QueryLink.class, new MPJLambdaWrapper<CfgActivityQuerylink>()
                        .leftJoin(CfgActivityQuerydatacol.class, "cd", CfgActivityQuerydatacol::getSplicecol, CfgActivityQuerylink::getSplicecol)
                        .selectAll(CfgActivityQuerylink.class)
                        .selectAll(CfgActivityQuerydatacol.class)
                        .eq(CfgActivityQuerylink::getStatus, 1)
                        .eq(CfgActivityQuerylink::getActivityid, item.getActivityid())
                        .orderByAsc("type"));
                XxlJobHelper.log("XXL-JOB-autoDistribute 自定义条件and(type=1):" + querylink.size() + "条.");
                System.out.println("querylink: " + querylink.size() + "条");

                // 定义案件对查询条件
                MPJLambdaWrapper<FiCreditcases> mpjLambdaWrapper = new MPJLambdaWrapper<>();
                //mpjLambdaWrapper.innerJoin(CreditAccount.class, "cda", CreditAccount::getAcct, FiCreditcases::getCreditAcct);
                //mpjLambdaWrapper.leftJoin(CreditAccountBalance.class, "cdb", CreditAccountBalance::getAcct, FiCreditcases::getCreditAcct);
                mpjLambdaWrapper.leftJoin(ConCustomer.class, "cu", ConCustomer::getCustomernumber, FiCreditcases::getCustomernumber);
                mpjLambdaWrapper.selectAll(FiCreditcases.class);
                //mpjLambdaWrapper.select(CreditAccount::getMthsOdue);
                //mpjLambdaWrapper.select(CreditAccountBalance::getSettledBillAmt, CreditAccountBalance::getSettledBillPrin, CreditAccountBalance::getSettledBillInt, CreditAccountBalance::getSettledBillFee, CreditAccountBalance::getPenchgAcc);
                mpjLambdaWrapper.eq("t.ccc", "O");
                mpjLambdaWrapper.and(i -> i.le("t.stopautodistenddt", LocalDateTime.now()).or().isNull("t.stopautodistenddt"));
                mpjLambdaWrapper.apply("fi_hasStopCall(t.creditcaseid,'CASE')<=0");

                if (item.getMthsOdue() != null) {
//                String[] mthsOdue = item.getMthsOdue().split(",");
//                List<Integer> ids = Arrays.stream(mthsOdue)
//                        .map(Integer::parseInt)
//                        .collect(Collectors.toList());
//                mpjLambdaWrapper.in("cda.mths_odue", ids);
                    mpjLambdaWrapper.ge("t.mths_odue", item.getMthsOdue());
                }
                if (item.getMthsOdue2() != null) {
                    mpjLambdaWrapper.le("t.mths_odue", item.getMthsOdue2());
                }
                if (item.getOverday1() != null) {
                    mpjLambdaWrapper.ge("t.mths_day", item.getOverday1());
                }
                if (item.getOverday2() != null) {
                    mpjLambdaWrapper.le("t.mths_day", item.getOverday2());
                }
                if (item.getAcctFlevel() != null && !item.getAcctFlevel().isEmpty()) {
                    mpjLambdaWrapper.eq("cu.flevel", item.getAcctFlevel());
                }
                if (item.getBusinesstype() != null && !item.getBusinesstype().isEmpty()) {
                    mpjLambdaWrapper.eq("t.prodtype", item.getBusinesstype());
                }
                if (item.getCusttags() != null && !item.getCusttags().isEmpty()) {
                    String tags = item.getCusttags().replace(",", "','");
                    mpjLambdaWrapper.exists("select 1 from con_customertag ct where ct.custid=t.customernumber and ct.id in ('" + tags + "')");
                }
                if (item.getCity() != null && !item.getCity().isEmpty()) {
                    String provinces = item.getCity().replace(",", "','");
                    mpjLambdaWrapper.exists("select 1 from con_address ca where ca.customernumber = t.customernumber and ca.province in ('" + provinces + "')");
                }

                querylink.forEach(x -> {
                    if (x.getMethod() != null && x.getSplicecol() != null && x.getColvalue() != null && x.getType() == 1) {
                        switch (x.getMethod()) {
                            case "=":
                                mpjLambdaWrapper.eq(x.getSplicecol(), x.getColvalue());
                                break;
                            case "!=":
                                mpjLambdaWrapper.ne(x.getSplicecol(), x.getColvalue());
                                break;
                            case "like":
                                mpjLambdaWrapper.like(x.getSplicecol(), x.getColvalue());
                                break;
                            case ">":
                                mpjLambdaWrapper.gt(x.getSplicecol(), x.getColvalue());
                                break;
                            case "<":
                                mpjLambdaWrapper.lt(x.getSplicecol(), x.getColvalue());
                                break;
                            case ">=":
                                mpjLambdaWrapper.ge(x.getSplicecol(), x.getColvalue());
                                break;
                            case "<=":
                                mpjLambdaWrapper.le(x.getSplicecol(), Objects.equals(x.getDatatype(), "numeric") ? new BigDecimal(x.getColvalue()) : x.getColvalue());
                                break;
                        }
                    }
                });
                long orcount = querylink.stream().filter(queryLink -> queryLink.getType() == 2).count();
                XxlJobHelper.log("XXL-JOB-autoDistribute 自定义条件or(type=2):" + orcount + "条.");
                if (orcount > 0) {
                    mpjLambdaWrapper.and(orWrapper -> {
                        querylink.forEach(x -> {
                            if (x.getMethod() != null && x.getSplicecol() != null && x.getColvalue() != null && x.getType() == 2) {
                                switch (x.getMethod()) {
                                    case "=":
                                        orWrapper.or().eq(x.getSplicecol(), x.getColvalue());
                                        break;
                                    case "!=":
                                        orWrapper.or().ne(x.getSplicecol(), x.getColvalue());
                                        break;
                                    case "like":
                                        orWrapper.or().like(x.getSplicecol(), x.getColvalue());
                                        break;
                                    case ">":
                                        orWrapper.or().gt(x.getSplicecol(), x.getColvalue());
                                        break;
                                    case "<":
                                        orWrapper.or().lt(x.getSplicecol(), x.getColvalue());
                                        break;
                                    case ">=":
                                        orWrapper.or().ge(x.getSplicecol(), x.getColvalue());
                                        break;
                                    case "<=":
                                        orWrapper.or().le(x.getSplicecol(), x.getColvalue());
                                        break;
                                }
                            }
                        });
                    });
                }

                // 过滤符合条件的案件
                List<FiCreditcases> caselist = fiCreditcasesMapper.selectJoinList(FiCreditcases.class, mpjLambdaWrapper);

                System.out.println("caselist: " + caselist.size() + "条");
                XxlJobHelper.log("XXL-JOB-autoDistribute 符合条件的案件:" + caselist.size() + "条.");
                XxlJobHelper.log("----------------------------------------");

                int count = caselist.size();
                //int sumamount = caselist.stream().map(CaseJoinAcct::getSettledBillAmt).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add).intValue();
                //BigDecimal sum_amount = caselist.stream().map(CaseJoinAcct::getSettledBillAmt).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);

                if (count > 0) {
                    List<CfgActivityOthergrplink> groups = cfgActivityOthergrplinkService.list(new QueryWrapper<CfgActivityOthergrplink>()
                            .eq("activityid", item.getActivityid())
                            .orderByDesc("radio"));
                    XxlJobHelper.log("XXL-JOB-autoDistribute 委外机构:" + groups.size() + "条.");
                    if (groups.size() > 0) {
                        int distype = item.getDistype();
                        int type = item.getDistype2();
                        //disUsersToCases(caselist, groups, distype, type, diffInDays, batchid);
                    } else {
                        XxlJobHelper.log("XXL-JOB-autoDistribute 请配置自动分案团队.");
                    }
                }
            } catch (Exception e) {
                XxlJobHelper.log("XXL-JOB-autoDistribute, 错误日志:" + e + ">>>>>【异常列】：" + item);
            }
        });
    }

    private void disUsersToCases(List<CfgActivity> list) {
        list.forEach(x -> {
            // 创建 JSON 对象
            JSONObject jsonObject = new JSONObject();
            // 固定字段
            jsonObject.put("taskid", x.getActivityid());
            jsonObject.put("tasktype", "dist");
            jsonObject.put("dismode", "1");
            String httpBody = jsonObject.toJSONString();
            XxlJobHelper.log("XXL-JOB-disUsersToCases, 请求参数:{}", httpBody);
            try {
                // 设置连接超时和响应超时
                Unirest.setTimeouts(30 * 60 * 1000, 60 * 1000);
                HttpResponse<JsonNode> jsonResponse = Unirest.post(cCrmurl + "/cpg/cpTaskDo")
                        .header("Content-Type", "application/json")
                        .header("Authorization", "Bearer " + cCrmToken)
                        .body(httpBody)
                        .asJson();
                // 获取响应体
                int status = jsonResponse.getStatus();
                JsonNode responseBody = jsonResponse.getBody();

                // 获取responseBody字段的值
                int code = responseBody.getObject().getInt("code");
                if (code == 200) {
                    XxlJobHelper.log("XXL-JOB-disUsersToCases, 自动分案成功");
                } else {
                    XxlJobHelper.log("XXL-JOB-disUsersToCases, 自动分案失败（状态码）：" + code);
                }
                XxlJobHelper.log("XXL-JOB-disUsersToCases, 调用Ccrm接口结束.status：{} >>>> responseBody：{}", status, responseBody);
            } catch (Exception e) {
                XxlJobHelper.log("XXL-JOB-disUsersToCases, 错误日志:" + e);
            }
        });
    }

    private void avgUsersToCases(List<CaseJoinAcct> caseList, List<CfgActivityOthergrplink> userList) {
        int totalCases = caseList.size(),
                totalUsers = userList.size(),
                casesPerUser = totalCases / totalUsers,   // 计算每个用户应该分配的案例数量
                extraCases = totalCases % totalUsers,     // 计算余下的案例数量
                caseIndex = 0;

        for (CfgActivityOthergrplink item : userList) {
            int assignedCases = casesPerUser + (extraCases > 0 ? 1 : 0); // 每个用户应该分配的案例数量
            for (int i = 0; i < assignedCases; i++) {
                caseList.get(caseIndex).setSendtodept(item.getGrpid());
                caseIndex++;
            }
            extraCases--; // 余下的案例数量减少
        }
    }

}
